<?php
namespace app\util;


use app\traits\EnvTrait;
use think\queue\command\Retry;

class YizunYiDong
{

    use EnvTrait;

    const ENV_TEST = 'test';
    const ENV_PROD = 'prod';

    // 应用appKey  测试
    //private $appKey = '20081';

    private $appKeyArr = [
        'test' => '20081',
        'prod' => [
            'commit' => '20125',
            'query' => '20126',
        ]
    ];
    // 公钥值 测试环境
    //private $appSecret = 'qgllgy8gogr';

    private $appSecretArr = [
        'test' => 'qgllgy8gogr',
        'prod' => [
            'commit' => 'ybt8ffaze7b',
            'query' => '3b53e6odxqh',
        ]
    ];

    // 交易成功状态
    const SUCCESS_CODE = [
        'TRADE_SUCCESS',
        'TRADE_FINISHED',
    ];

    //下单接口 测试服
    const Test_Trade_URL = 'www.baidu.com';
    //下单接口 正式服
    const Pro_Trade_URL = 'www.baidu.com';

    private $method;
    private $version;
    private $businessCode = 'C1SsCK3ptPRKosbW';
    private $token;

    public function __construct($method, $messageFormat, $locale, $version)
    {
        $this->method = $method;
        $this->messageFormat = $messageFormat;
        $this->locale = $locale;
        $this->version = $version;
    }

    public function getToken($traceId)
    {
        $params = [
            'appKey' => $this->getAppKey('commit'),
            //'appKey' => '20081',
            'method' => 'outerService.cmCardGetToken',
            'locale' => $this->locale ?: 'zh_CN',
            'messageFormat' => $this->messageFormat ?: 'json',
            'v' => '1.0',
            'businessCode' => $this->businessCode
        ];
//        dump($params);die;
        $params = $this->makeSign($params);
        $result = Tools::curlPost($this->getUrl(), $params, false);
        if ($result['code'] === '00000000') {
            $this->token = $result['bizToken'];

            $redis = new CacheHelper();
            $redis->set('token:yidong:'.$traceId, $result['bizToken']);

            return $result['bizToken'];
        } else {
            $this->token = '';
            return '';
        }
    }

    //下单
    public function addTrade($data)
    {

        $redis = new CacheHelper();
        $token = $redis->get('token:yidong:'.$data['traceId']);
        $params = array_merge([
            'appKey' => $this->getAppKey(),
            //'appKey' => '20081',
            'method' => $this->method,
            'locale' => $this->locale,
            'messageFormat' => $this->messageFormat,
            'v' => '1.0',
            'businessCode' => $this->businessCode,
            'bizToken' => $token,
        ],$data);


        unset($params['traceId']);
        $params = $this->makeSign($params);
        $params['sourceUrl'] =  urlencode($params['sourceUrl']);
//        dump($params);die;
        $result = Tools::curlPost($this->getUrl(), $params,false);
//        dump($result);die;
        if ($result['code'] === '00000000') {
            $data = ['tradeId' => $result['tradeId']];
            return ['code' => 0, 'data'=>$data];
        } else {
            if ($result['code'] == '10200011') {
                $result['code'] = 10021;
            }
            return ['code' => $result['code']??1, 'message' => $result['message']??''];
        }
    }

    //查询
    public function query($data)
    {
        $params = [
            //'appKey' => $this->appKey,
            'appKey' => $this->getAppKey('query'),
            'method' => $this->method,
            'locale' => $this->locale,
            'messageFormat' => $this->messageFormat,
            'v' => $this->version,
            'param' => $data
        ];

        $params = $this->makeSign($params, 'query');

        $result = Tools::curlPost($this->getUrl(), $params, false);
        if ($result['code'] === '00000000') {
            return ['code' => 0, 'data' => $result['data'] ?? [] ];
        } else {
            return ['code' => $result['code'], 'message' => $result['message']];
        }


    }

    //选号
    public function selectPhoneNum($data)
    {
        $token = $this->getToken($data['traceId']);
        if (empty($token)) {
            return ['code' => 10021, 'message' => 'token获取失败'];
        }
        $params = [
            'appKey' => $this->getAppKey(),
            //'appKey' => '20081',
            'method' => $this->method,
            'locale' => $this->locale,
            'v' => $this->version,
            'messageFormat' => $this->messageFormat,
            'city' => $data['cityCode'],
            'province' => $data['provinceCode'],
            'pageNo' => $data['pageNo'] ?: 1,
            'businessCode' => $this->businessCode,
            'bizToken' => $token,
        ];

        $params = $this->makeSign($params);
        $result = Tools::curlPost($this->getUrl(), $params, false);
//        dump($result);die;
        $phoneNums = [];
        if ($result['code'] === '00000000') {
            $phoneNumList = json_decode($result['phoneNumList'],true);
            $numbers = array_column($phoneNumList, 'number');
            $phoneNums = json_encode($numbers);
            //return  ['code' => $result['code'], 'data' => $result['data'] ?? [] ];
            return  ['code' => 0, 'data' => ['phoneNums' => $phoneNums] ];
        } else {
            return ['code' => $result['code'], 'message' => $result['message']];
        }

    }


    //验证号码是否被占用
    public function isOccupy($data)
    {
        $redis = new CacheHelper();
        $token = $redis->get('token:yidong:'.$data['traceId']);
        if (empty($token)) {
            return ['code' => 10021, 'message' => 'token过期'];
        }
        $params = [
            'appKey' => $this->getAppKey(),
            //'appKey' => '20081',
            'method' => $this->method,
            'locale' => $this->locale,
            'v' => $this->version,
            'messageFormat' => $this->messageFormat,
            'phoneNum' => $data['phoneNum'],
            'businessCode' => $this->businessCode,
            'bizToken' => $token,
        ];
        $params = $this->makeSign($params);
        $result = Tools::curlPost($this->getUrl(), $params, false);

        if ($result['code'] === '00000000') {
            return ['code' => 0];
        } else {
            if ($result['code'] == '01001003') {
                $result['code'] = 10021;
            }
            return ['code' => $result['code'], 'message' => $result['message']];
        }

    }

    //验证号码是否被占用
    public function validate($data)
    {
        $params = [
            'appKey' => $this->getAppKey(),
            'method' => $this->method,
            'locale' => $this->locale,
            'v' => $this->version,
            'messageFormat' => $this->messageFormat,
            'params' => $data['params'],
            'chanId' => self::inEnvTesting() ? 20081 : 20125,
        ];

        $params = $this->makeSign($params);
        $result = Tools::curlPost($this->getUrl(), $params, false);
        if (isset($result['code']) && $result['code'] === '00000000') {
            return ['code' => 0];
        } else {
            return ['code' => $result['resData'][0]['gztCode'] ?? $result['code'] ?? 1 , 'message' =>  $result['resData'][0]['gztDesc']] ?? $result['message'] ?? '';
        }

    }


    /**
     * 获取签名
     */
    function makeSign($params, $type = 'commit')
    {

        ksort($params);

        $buff = "";
        foreach ($params as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . $v;
            }
        }
        $appSecret = $this->getSecret($type);
        //$appSecret = 'qgllgy8gogr';
        $sign_str = $appSecret  . $buff . $appSecret;
        $sign_str = htmlspecialchars_decode($sign_str);
        $params['sign'] = strtoupper(sha1($sign_str));

        //var_dump($params['sign']); ;die;
        return $params;
    }

    private function getAppKey($type = 'commit')
    {
        $env = env('APP_ENV');
        return self::inEnvTesting() ? $this->appKeyArr[$env] : $this->appKeyArr[$env][$type];
    }

    private function getSecret($type = 'commit')
    {
        $env = env('APP_ENV');
        return self::inEnvTesting() ? $this->appSecretArr[$env] : $this->appSecretArr[$env][$type];
    }

    private function getUrl()
    {
        return self::inEnvTesting() ? self::Test_Trade_URL : self::Pro_Trade_URL;
    }
}
